/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import Modele.Administrateur;
import Modele.Technicien;
import Modele.Utilisateur;
import Utils.Constantes;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 *
 * @author 20cent
 */
public class UtilisateurDAOmysql extends AbstractDAO implements UtilisateurDao {

    private static final String SQL_INSERT = "INSERT INTO `nemo_velo`.`" + ChampsBDD.TABLE_UTILISATEUR + "` (`"
            + ChampsBDD.UTILISATEUR_ID + "`, `"
            + ChampsBDD.UTILISATEUR_NOM + "`, `"
            + ChampsBDD.UTILISATEUR_PRENOM + "`, `"
            + ChampsBDD.UTILISATEUR_TYPE + "`, `"
            + ChampsBDD.UTILISATEUR_EQUIPEMENT
            + "`) VALUES (NULL, ?, ?, ?, ?);";
    private static final String SQL_UPDATE = "UPDATE `nemo_velo`.`" + ChampsBDD.TABLE_UTILISATEUR + "` SET `"
            + ChampsBDD.UTILISATEUR_NOM + "` = ?, `"
            + ChampsBDD.UTILISATEUR_PRENOM + "` = ?, `"
            + ChampsBDD.UTILISATEUR_TYPE + "` = ?, `"
            + ChampsBDD.UTILISATEUR_EQUIPEMENT + "` = ? "
            + "WHERE `" + ChampsBDD.UTILISATEUR_ID + "` = ?;";
    private static final String SQL_SELECT_PAR_ID = "SELECT * "
            + "FROM  `" + ChampsBDD.TABLE_UTILISATEUR + "` "
            + "WHERE  `" + ChampsBDD.UTILISATEUR_ID + "` = ?";
    private static final String SQL_SELECT_PAR_TYPE = "SELECT * "
            + "FROM  `" + ChampsBDD.TABLE_UTILISATEUR + "` "
            + "WHERE  `" + ChampsBDD.UTILISATEUR_TYPE + "` = ?";

    public UtilisateurDAOmysql(DAOFactory daoFactory) {
        super(daoFactory);
    }

    @Override
    public void save(Utilisateur utilisateur) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet valeursAutoGenerees = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            int type = 2;
            String equipement = null;
            if (utilisateur instanceof Technicien) {
                equipement = ((Technicien) utilisateur).getMEquipement();
            } else {
                type = 1;
            }
            preparedStatement = initialisationRequetePreparee(connexion, SQL_INSERT, true, utilisateur.getMNom(), utilisateur.getMPrenom(), type, equipement);
            int statut = preparedStatement.executeUpdate();
            /* Analyse du statut retourné par la requête d'insertion */
            if (statut == 0) {
                throw new DAOException("Échec de la création de l'utilisateur, aucune ligne ajoutée dans la table.");
            }
            /* Récupération de l'id auto-généré par la requête d'insertion */
            valeursAutoGenerees = preparedStatement.getGeneratedKeys();
            if (valeursAutoGenerees.next()) {
                /* Puis initialisation de la propriété id du bean Utilisateur avec sa valeur */
                utilisateur.setMId(valeursAutoGenerees.getInt(1));
            } else {
                throw new DAOException("Échec de la création de l'utilisateur en base, aucun ID auto-généré retourné.");
            }
        } catch (SQLException e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(valeursAutoGenerees, preparedStatement, connexion);
        }
    }

    @Override
    public void update(Utilisateur utilisateur) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet valeursAutoGenerees = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            int type = 2;
            String equipement = null;
            if (utilisateur instanceof Technicien) {
                equipement = ((Technicien) utilisateur).getMEquipement();
            } else {
                type = 1;
            }
            preparedStatement = initialisationRequetePreparee(connexion, SQL_UPDATE, false, utilisateur.getMNom(), utilisateur.getMPrenom(), type, equipement, utilisateur.getMId());
            int statut = preparedStatement.executeUpdate();
            /* Analyse du statut retourné par la requête d'insertion */
            if (statut == 0) {
                throw new DAOException("Échec de la création de l'utilisateur, aucune ligne ajoutée dans la table.");
            }

        } catch (SQLException e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(valeursAutoGenerees, preparedStatement, connexion);
        }
    }

    @Override
    public Utilisateur getByID(int id) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Utilisateur utilisateur = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_SELECT_PAR_ID, false, id);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            if (resultSet.next()) {
                utilisateur = map(resultSet);
            }
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(resultSet, preparedStatement, connexion);
        }
        return utilisateur;
    }

    @Override
    public ArrayList<Utilisateur> getByType(int type) throws DAOException {
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<Utilisateur> liste = new ArrayList<>();

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee(connexion, SQL_SELECT_PAR_TYPE, false, type);
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            while (resultSet.next()) {
                liste.add(map(resultSet));
            }
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            fermeturesSilencieuses(resultSet, preparedStatement, connexion);
        }
        return liste;
    }


    /*
     * Simple méthode utilitaire permettant de faire la correspondance (le
     * mapping) entre une ligne issue de la table des utilisateurs (un
     * ResultSet) et un bean Utilisateur.
     */
    public static Utilisateur map(ResultSet resultSet) throws SQLException {
        Utilisateur utilisateur;
        int type = resultSet.getInt(ChampsBDD.UTILISATEUR_TYPE);
        if (type == Constantes.TYPE_ADMIN) {
            utilisateur = new Administrateur();
        } else {
            utilisateur = new Technicien();
            ((Technicien) utilisateur).setMEquipement(resultSet.getString(ChampsBDD.UTILISATEUR_EQUIPEMENT));
        }
        utilisateur.setMId(resultSet.getInt(ChampsBDD.UTILISATEUR_ID));
        utilisateur.setMNom(resultSet.getString(ChampsBDD.UTILISATEUR_NOM));
        utilisateur.setMPrenom(resultSet.getString(ChampsBDD.UTILISATEUR_PRENOM));

        return utilisateur;
    }
}